package com.dhy.handle;

import com.dhy.util.FileReaderUtil;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 文件操作处理器
 * </p>
 *
 * @author 大忽悠
 * @create 2022/7/5 10:55
 */
@Slf4j
public class FileHandler {
    /**
     * 挑选一个副本实例读取
     */
    private static File PART_TBL_FILE;

    /**
     * 四个实例分片读取
     */
    private static File LINEITEM_TBL_FILE;

    /**
     * 分片信息分隔符
     */
    private static String INDEX_INFO_SEPARATOR="-";

    /**
     * 每个实例的读取范围:
     * 主实例: 0-99 (单位字节)
     * 副本1: 100-199
     * 副本2: 200-299
     * 副本3: 300-399
     * 副本4: 400-599
     * (起始字节如果不是换行符,那就往后面找,找到第一个换行符后开始读取。
     * 如果结束字节不是换行符,那就往后读取,一直读取第一个换行符结束。)
     *
     * <p>
     * 1.计算LINEITEM_TBL_FILE文件大小
     * 2.除4,计算每个实例应该读取多少字节数据(平均每个实例读取2G)
     * </p>
     */
    public static List<String> getIndex() {
        long len = LINEITEM_TBL_FILE.length();
        long singleOneRead = len / 4;
        return Arrays.asList(
                "0-" + singleOneRead,
                singleOneRead + 1 + "-" + 2 * singleOneRead,
                2 * singleOneRead + 1 + "-" + 3 * singleOneRead,
                3 * singleOneRead + 1 + "-" +len);
    }


    /**
     * 按照分片信息对LINEITEM_TBL_FILE文件进行读取
     * @return
     */
    public static List<String> readByIndex(String indexInfo) throws IOException {
        String[] indexs = indexInfo.split(INDEX_INFO_SEPARATOR);
        Long begin=  Long.parseLong(indexs[0]);
        Long end=  Long.parseLong(indexs[1]);
        Long num=end-begin;
        log.info("当前实例需要从{},读取到{},一共{}字节",begin,end,num);
        return doReadByIndex(begin,end,num);
    }

    /**
     * 读取partTblFile---主实例负责读取---并发读取
     */
    public static List<String> readPartTblFile() throws IOException {
        long start=System.currentTimeMillis();
        List<String> res = FileReaderUtil.concurrentReadIndex(new RandomAccessFile(PART_TBL_FILE, "r"), PART_TBL_FILE.length());
        log.info("当前实例读取完毕,总共耗时: {}",System.currentTimeMillis()-start);
        return res;
    }

    /**
     * 根据分片范围读取数据
     * (起始字节如果不是换行符,那就往后面找,找到第一个换行符后开始读取。
     * 如果结束字节不是换行符,那就往后读取,一直读取第一个换行符结束。)
     */
    public static List<String> doReadByIndex(Long begin,Long end,Long num) throws IOException {
        long start = System.currentTimeMillis();
        RandomAccessFile accessFile = new RandomAccessFile(LINEITEM_TBL_FILE,"r");
        accessFile.seek(begin);
        //从新的一行开始读取
        FileReaderUtil.skipToNewLine(accessFile);
        //每次读取一行,直到读取的总字节数大于等于num为止
        List<String> res = FileReaderUtil.concurrentReadIndex(accessFile, num);
        log.info("当前实例读取完毕,总共耗时: {}",System.currentTimeMillis()-start);
        return res;
    }

    public static void setPartTblFile(File partTblFile) {PART_TBL_FILE = partTblFile;}

    public static void setLineitemTblFile(File lineitemTblFile) {
        LINEITEM_TBL_FILE = lineitemTblFile;
    }

}
